`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    11:07:11 11/19/2020 
// Design Name: 
// Module Name:    alu 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
include "defines.v";

module ALU(
    input [31:0] a1,
    input [31:0] a2,
	 input [4:0] shamt,
    input [4:0] aluOp,
    output [31:0] aluResult
    );
	reg [31:0]temp;
	always @*
	begin
		case (aluOp)
			`aluSUB:
				temp = $signed(a1) - $signed(a2);
			`aluSUBU:
				temp = $signed(a1) - $signed(a2);	
			`aluADD:
				temp = $signed(a1) + $signed(a2);
			`aluADDU:
				temp = $signed(a1) + $signed(a2);
			`aluAND:
				temp = a1 & a2;
			`aluOR:
				temp = a1 | a2;
			`aluXOR:
				temp = a1 ^ a2;
			`aluNOR:
				temp = ~(a1 | a2);
			`aluSLT:
				temp = $signed(a1) < $signed(a2) ? 1 : 0;
			`aluSLTU:
				temp = a1 < a2 ? 1 : 0;
			`aluSLL:
				temp = a2 << shamt;
			`aluSRL:
				temp = a2 >> shamt;
			`aluSRA:
				temp = $signed(a2) >>> shamt;
			`aluSLLV:
				temp = a2 << {{27'd0},a1[4:0]};
			`aluSRLV:
				temp = a2 >> {{27'd0},a1[4:0]};
			`aluSRAV:
				temp = $signed(a2) >>> {{27'd0},a1[4:0]};
			default:
				temp = 0;
		endcase
	end
	
	assign aluResult = temp;

	
endmodule
